package com.hzit.payweb.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hzit.paycommon.paycommonapi.aliapy.AliapyTradeQueryReq;
import com.hzit.paycommon.paycommonapi.aliapy.AlipayPrePayReq;
import com.hzit.paycommon.paycommonapi.aliapy.resp.AlipayPrePayRespData;
import com.hzit.paycommon.paycommonapi.aliapy.resp.AlipayTradeQueryRespData;
import com.hzit.paycommon.paycommonapi.enums.PayWayEnum;
import com.hzit.paycommon.paycommonapi.enums.StatusEnum;
import com.hzit.paycommon.paycommonapi.req.PayQueryReq;
import com.hzit.paycommon.paycommonapi.req.PayReq;
import com.hzit.paycommon.paycommonapi.resp.RespVo;
import com.hzit.paycommon.paycommonapi.utils.PayUtil;
import com.hzit.payweb.factory.PayFactory;
import com.hzit.payweb.iclient.IAlipayFrontClient;
import com.hzit.payweb.model.MchInfo;
import com.hzit.payweb.model.MchPayWay;
import com.hzit.payweb.model.PaySerial;
import com.hzit.payweb.service.IMchInfoService;
import com.hzit.payweb.service.IPaySerialService;
import com.hzit.payweb.service.IPayService;
import com.hzit.payweb.service.IPayStrategy;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.HashMap;

/**
 * 支付相关接口实现类
 */
@Service
//@Scheduled 实现定时任务
public class PayServiceImpl implements IPayService {

    private Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private IMchInfoService mchInfoService;

    @Autowired
    private IPaySerialService paySerialService;

    @Autowired
    private PayFactory payFactory;

    @Autowired
    private IAlipayFrontClient iAlipayFrontClient;

//    @Autowired
//    private

    @Override
    public RespVo payCreate(PayReq payReq) {
        //1.参数校验
        //验证签名

        RespVo  respVo = new RespVo ();
        MchInfo mchInfo = mchInfoService.queryByMchId(payReq.getMchId());
        if(ObjectUtils.isEmpty(mchInfo)){
            respVo.setCode(-1);
            respVo.setMsg("商户号不存在");
            logger.info("订单号：{}，商户号不存在",payReq.getMchOrderNo());
            return respVo;
        }

        MchPayWay mchPayWay = mchInfoService.queryByMchIdAndPayWay(payReq.getMchId(),payReq.getPayWay());

        if(ObjectUtils.isEmpty(mchPayWay)){
            respVo.setCode(-1);
            respVo.setMsg("商户不支持此支付方式");
            logger.info("订单号：{}，商户不支持此支付方式",payReq.getMchOrderNo());
            return respVo;
        }

        JSONObject parms = (JSONObject) JSONObject.toJSON(payReq);

        //签名验证
        boolean flag = PayUtil.verifyPaySign(parms,mchInfo.getReqKey());
        if(!flag){
            respVo.setCode(-1);
            respVo.setMsg("非法请求");
            logger.info("订单号：{}，非法请求",payReq.getMchOrderNo());
            return respVo;
        }

        //4.生成待支付的流水
        PaySerial paySerial = paySerialService.createPaySerial(payReq);

        //策略+工厂 解决 if else 过多的问题                        "扫码支付的code"
        IPayStrategy iPayStrategy = payFactory.getPayStrategy(payReq.getPayWay());


        if(ObjectUtils.isEmpty(iPayStrategy)){
            respVo.setCode(-1);
            respVo.setMsg("不支持该支付方式："+payReq.getPayWay());
            logger.info("订单号：{}，不支持该支付方式",payReq.getMchOrderNo());
            return respVo;
        }
             // iPayStrategy = AlpayPrePayStrategyImpl.pay
        //6.封装返回
        return iPayStrategy.pay(paySerial);


    }

    /**
     * 查询支付流水状态
     * @param queryReq
     * @return
     */
    @Override
    public RespVo payResultQuery(PayQueryReq queryReq) {
        RespVo respVo = new RespVo();

        //1.检查数据queryReq，。

        //2.查询交易流水表中的状态
        PaySerial paySerial = paySerialService.queryInfoByOutTradeNo(queryReq.getSerialNo());

        paySerial.setPayWay("alipay");

        if (ObjectUtils.isEmpty(paySerial)){
            respVo.setCode(-1);
            respVo.setMsg("不存在该流水");
            return respVo;
        }

        if(String.valueOf(StatusEnum.SUCCESS.getCode())== paySerial.getStatus()){
            respVo.setCode(0);
            respVo.setMsg(paySerial.getRespMsg());
            return respVo;
        }

        if(String.valueOf(StatusEnum.FAIL.getCode())== paySerial.getStatus()){
            respVo.setCode(-1);
            respVo.setMsg(paySerial.getRespMsg());
            return respVo;
        }


        //3.交易流水表中，还是未支付，支付中。调用支付宝的接口去查。

        if(String.valueOf(StatusEnum.PAYING.getCode()) == paySerial.getStatus()
                || String.valueOf(StatusEnum.UNPAY.getCode()) == paySerial.getStatus()) {

            if("alipay".equals(paySerial.getPayWay())){
                //调用支付宝支付查询
                AliapyTradeQueryReq tradeQueryReq = new AliapyTradeQueryReq();
                RespVo<AlipayTradeQueryRespData> respDataRespVo = iAlipayFrontClient.tradeQuery(tradeQueryReq);

                if(respDataRespVo.getCode() != 0){

                    return null;
                }

                AlipayTradeQueryRespData alipayTradeQueryRespData = respDataRespVo.getData();

                //1.更新数据库流水
                PaySerial record = new PaySerial();
                record.setId(paySerial.getId());
                record.setRespSerialNo(alipayTradeQueryRespData.getTradeNo());
                record.setUpdateTime(new Date());
                record.setStatus(String.valueOf(StatusEnum.SUCCESS.getCode()));  //TODO
                record.setRespMsg(StatusEnum.SUCCESS.getDesc()); //TODO
                paySerialService.updatePaySerialStatus(record);

                //2.返回给业务系统
                respVo.setData(alipayTradeQueryRespData);
            }

        }
        return respVo;
    }

    @Override
    public RespVo queryTradeing(String payWay) {

        RespVo respVo = new RespVo();

        JSONArray  array = new JSONArray();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("outTradeNo","1297801489347121152");
        jsonObject.put("tradeNo","");

        array.add(jsonObject);

        jsonObject = new JSONObject();
        jsonObject.put("outTradeNo","1297803973604020224");
        jsonObject.put("tradeNo","");
        array.add(jsonObject);


        respVo.setData(array);
        return respVo;
    }

}
